package preSetExceperement;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Hashtable;
import java.util.LinkedList;

import Blocks.Block;
import Blocks.InitialBlock;
import Blocks.NextState;
import Blocks.NextstateIntial;


public class TreeRules 
{
	private Hashtable<BitSet , BitSet> previousBlocks;
	private ArrayList<BitSet> positions;
	
 
	public TreeRules()
	{
		previousBlocks = new Hashtable<BitSet, BitSet>();
		positions = new ArrayList<BitSet>();
	}
	
	
	
	public boolean applyRule1 (Block currentBlock)
	{
		LinkedList<NextState> states = currentBlock.getNode();
		for(int i=0;i<states.size();i++)
		{
			NextState currentState = states.get(i);
			String elements = currentState.getNextState().toString();
			if(elements.length()-2!=1)
			{
				return  false;
			}
		}
		return true;
	}
	
	
	public boolean applyRule1Initial (InitialBlock currentBlock)
	{
		LinkedList<NextstateIntial> states = currentBlock.getNode();
		for(int i=0;i<states.size();i++)
		{
			NextstateIntial currentState = states.get(i);
			String elements = currentState.getNextState().toString();
			if(elements.length()-2!=1)
			{
				return  false;
			}
		}
		return true;
	}

	
	
	public boolean applyRule2 (Block currentBlock,int index)
	{
		boolean x= true;
		LinkedList<NextState> states = currentBlock.getNode();
		for(int i=0;i<states.size();i++)
		{
			NextState currentState = states.get(i);
			BitSet elements = currentState.getNextState();
			if(previousBlocks.containsKey(elements))
			{
				BitSet blocksHaveSameParts = previousBlocks.get(elements);
				blocksHaveSameParts.set(index);
				positions.add(elements);
				previousBlocks.put(elements, blocksHaveSameParts);
			}
			else
			{
				BitSet blockParts = new BitSet();
				blockParts.set(index);
				previousBlocks.put(elements, blockParts);
				x= false;
			}
		}
		if(!x && positions.size()!=0)
		{
			BitSet first = positions.get(0);
			BitSet required = previousBlocks.get(first);
			int i=1;
			while(i<positions.size()&&(!first.isEmpty())){
				required.and( previousBlocks.get(positions.get(i)));
				i++;
			}
			if(required.isEmpty())
			{
				x= false;
			}	
		}
		return x;
	}
	
	public boolean applyRule2Initial (InitialBlock currentBlock,int index)
	{
		boolean x= true;
		LinkedList<NextstateIntial> states = currentBlock.getNode();
		for(int i=0;i<states.size();i++)
		{
			NextstateIntial currentState = states.get(i);
			BitSet elements = currentState.getNextState();
			if(previousBlocks.containsKey(elements))
			{
				BitSet blocksHaveSameParts = previousBlocks.get(elements);
				blocksHaveSameParts.set(index);
				positions.add(elements);
				previousBlocks.put(elements, blocksHaveSameParts);
			}
			else
			{
				BitSet blockParts = new BitSet();
				blockParts.set(index);
				previousBlocks.put(elements, blockParts);
				x= false;
			}
		}
		if(!x && positions.size()!=0)
		{
			BitSet first = positions.get(0);
			BitSet required = previousBlocks.get(first);
			int i=1;
			while(i<positions.size()&&(!first.isEmpty())){
				required.and( previousBlocks.get(positions.get(i)));
				i++;
			}
			if(required.isEmpty())
			{
				x= false;
			}	
		}
		return x;
	}


	public void init()
	{
		positions = new ArrayList<BitSet>();
	}
	
	
//	public boolean  setBlocks (BitSet blockBitSet ,int index )
//	{
//		
//		if(previousBlocks.containsKey(blockBitSet))
//		{
//			BitSet blocksHaveSameParts = (BitSet) previousBlocks.get(blockBitSet).clone();
//			positions.add(blockBitSet);
//			blocksHaveSameParts.set(index);
//			previousBlocks.put(blockBitSet, blocksHaveSameParts);
//			return true;
//		}
//		else
//		{
//			BitSet blocksHaveSameParts = new BitSet();
//			blocksHaveSameParts.set(index);
//			previousBlocks.put(blockBitSet,blocksHaveSameParts);
//			return false;
//		}
//	}
//
//	public boolean checkRule2 ()
//	{
//		// true rule2 is satisfied
//		if(positions.size()==0){
//			return false;
//		}
//		BitSet first = positions.get(0);
////		System.out.println("first"+first);
//		BitSet required = previousBlocks.get(first);
////		System.out.println("req"+required.toString());
//		int i=1;
//		while(i<positions.size()&&(!first.isEmpty())){
////			System.out.println("size"+positions.size());
////			System.out.println("index"+i);
//			required.and( previousBlocks.get(positions.get(i)));
////			System.out.println("pos"+positions.get(i));
////			System.out.println("pre"+previousBlocks.get(positions.get(i)));
////			System.out.println("req2"+required);
//			i++;
//		}
//		String bitSetElements = required.toString();
//		 int length = bitSetElements.length()-2;
//		if(first.isEmpty())
//		{
//			return false;
//		}
//		else if(length>2){
//			
//			System.out.println("Wrong");
//		}
//		return true;
//	}
//	
//	
//	public void init()
//	{
//		positions = new ArrayList<BitSet>();
//	}
//	
//	public Hashtable<BitSet, BitSet> getPreviousBlocks() {
//		return previousBlocks;
//	}
//
//	public void setPreviousBlocks(Hashtable<BitSet, BitSet> previousBlocks) {
//		this.previousBlocks = previousBlocks;
//	}
//	
//	public static void main(String[] args) {
//		 Hashtable<BitSet , BitSet> previousBlocks = new Hashtable<BitSet, BitSet>();
//		 BitSet x = new BitSet();
//		 x.set(1);
//		 x.set(2);
//		 BitSet x1 = new BitSet();
//		 x1.set(1);
//		 x1.set(3);
//		 BitSet x2 = new BitSet();
//		 x2.set(1);
//		 x2.set(4);
//		 BitSet m = new BitSet();
//		 m.set(1);
//		 m.set(2);
//		 BitSet m1 = new BitSet();
//		 m1.set(1);
//		 m1.set(3);
//		 previousBlocks.put(x,m);
//		 previousBlocks.put(x1, m1);
//		 TreeRules k = new  TreeRules();
//		 k.setPreviousBlocks(previousBlocks);
//
//		 System.out.println(k.setBlocks(x,3));
//		 System.out.println(k.getPreviousBlocks().get(x).toString());
//		 System.out.println(k.setBlocks(x1,3));
//		 
//		 System.out.println(k.getPreviousBlocks().get(x1).toString());
//
//
//		 
//		 System.out.println(m.toString());
//		 System.out.println(k.checkRule2());
//	}

	
}
